﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Windows.Input;
using MouseExtender.Logic.Common;
using MouseExtender.Logic.Enums;
using MouseExtender.Logic.Managers;

namespace MouseExtender.Logic.Entities
{
    [DataContract]
    public class UserSettings
    {
        #region Private field

        private List<LauncherItem> _launcherItems = null;
        private List<TabInfo> _tabInfoList = null;
        private DateTime? _updateTime = null;
        private RestartOptions? _shutdownAction = null;
        private bool? _forceAction = null;
        private TimeSpan? _actionSpan = null;
        private TimerScalePeriod? _actionSpanScale = null;
        private MouseExtenderButton _mouseKeys;
        private Guid? _appInstanceId;

        #endregion

        public event EventHandler Changed;

        public UserSettings()
        {
            //defaults
            IconSize = IconSize.Icon32x32;
            ItemsInRow = 5;
            ExcludedPrograms = new ObservableCollection<ExcludedProgram>();
            ShowSystemButtonsBar = true;
            _mouseKeys = MouseExtenderButton.MiddleButton;
            Key = System.Windows.Forms.Keys.F4;
            Modifier = ModifierKeys.None;
        }

        #region Properties (Data Members)

        [DataMember(IsRequired = false)]
        public Guid? ApplicationInstanceId
        {
            get { return _appInstanceId; }
            private set
            {
                _appInstanceId = value;
                SettingChanged();
            }

        }

        [DataMember]
        public List<LauncherItem> LauncherItems
        {
            get
            {
                if (_launcherItems == null)
                    return _launcherItems = new List<LauncherItem>();
                else
                    return _launcherItems;
            }
            set
            {
                _launcherItems = value;
                SettingChanged();
            }
        }

        [DataMember(IsRequired = false)]
        public List<TabInfo> TabInfoList
        {
            get
            {
                if (_tabInfoList == null)
                    return _tabInfoList = new List<TabInfo>();
                else
                    return _tabInfoList;
            }
            set
            {
                _tabInfoList = value;
                SettingChanged();
            }
        }

        [DataMember]
        public IconSize IconSize
        { get; set; }

        [DataMember]
        public int ItemsInRow
        { get; set; }

        [DataMember(IsRequired = false)]
        public ObservableCollection<ExcludedProgram> ExcludedPrograms
        { get; set; }

        [DataMember]
        public bool ShowSystemButtonsBar
        { get; set; }

        [DataMember(IsRequired = false)]
        public bool HideOnMiddleClickWhenOpened
        { get; set; }

        [DataMember]
        public bool DontHidePanel
        { get; set; }

        [DataMember]
        public bool IsDisable
        { get; set; }

        [DataMember]
        public bool HideCloseButton
        { get; set; }

        [DataMember(IsRequired = false)]
        public CheckUpdatesPeriod? CheckUpdatesPeriod
        { get; set; }

        [DataMember(IsRequired = false)]
        public DateTime? LastUpdatesCheck
        {
            get
            {
                return _updateTime;
            }
            set
            {
                _updateTime = value;
                SettingChanged();
            }
        }

        [DataMember(IsRequired = false)]
        public RestartOptions? ShutdownAction
        {
            get
            {
                return _shutdownAction;
            }
            set
            {
                if (_shutdownAction != value)
                {
                    _shutdownAction = value;
                    SettingChanged();
                }
            }
        }

        [DataMember(IsRequired = false)]
        public bool? ForceAction
        {
            get { return _forceAction; }
            set
            {
                if (_forceAction != value)
                {
                    _forceAction = value;
                    SettingChanged();
                }
            }
        }

        [DataMember(IsRequired = false)]
        public TimerScalePeriod? ActionSpanScale
        {
            get { return _actionSpanScale; }
            set
            {
                if (_actionSpanScale != value)
                {
                    _actionSpanScale = value;
                    SettingChanged();
                }
            }
        }


        [DataMember(IsRequired = false)]
        public TimeSpan? ActionSpan
        {
            get { return _actionSpan; }
            set
            {
                if (_actionSpan != value)
                {
                    _actionSpan = value;
                    SettingChanged();
                }
            }
        }

        [DataMember(IsRequired = false)]
        public MouseExtenderButton MouseKeysCombination
        {
            get
            {
                return _mouseKeys;
            }
            set
            {
                _mouseKeys = value;
            }
        }

        [DataMember(IsRequired = false)]
        public string UICulture
        {
            get;
            set;
        }


        [DataMember(IsRequired = false)]
        public InternetAccessConfigurationType? InternetAccessConfigType { get; set; }

        [DataMember(IsRequired = false)]
        public string HttpProxy { get; set; }

        [DataMember(IsRequired = false)]
        public bool UseProxyAuthentication { get; set; }

        [DataMember(IsRequired = false)]
        public string ProxyUserName { get; set; }

        [DataMember(IsRequired = false)]
        public string ProxyPassword { get; set; }

        [DataMember(IsRequired = false)]
        public bool UseHWAcceleration { get; set; }

        [DataMember(IsRequired = false)]
        public System.Windows.Forms.Keys Key { get; set; }

        [DataMember(IsRequired = false)]
        public ModifierKeys Modifier { get; set; }

        #endregion

        #region Methods
        public void SettingChanged()
        {
            if (Changed != null)
                Changed.Invoke(this, new EventArgs());
        }

        public void AddExcludedProgram(string executablePath)
        {
            ExcludedPrograms.Add(new ExcludedProgram()
            {
                ExecutablePath = executablePath.ToUpper(),
                Name = Path.GetFileName(executablePath).ToUpper(),
            });
        }

        public bool IsProgramExcluded(string fileName, bool isPath)
        {
            bool result = false;
            string fileNameUpper = fileName.ToUpper();
            if (ExcludedPrograms.Any(ep => isPath ? (ep.ExecutablePath == fileNameUpper) : (ep.Name.Contains(fileNameUpper))))
            {
                result = true;
            }
            return result;
        }

        public void SetParametersDefaultsIfValueNotSpecified()
        {
            this.Changed += SettingsChanged;

            if (!ApplicationInstanceId.HasValue)
                ApplicationInstanceId = Guid.NewGuid();

            if (!ShutdownAction.HasValue)
                ShutdownAction = RestartOptions.ShutDown;

            if (!ForceAction.HasValue)
                ForceAction = true;

            if (!ActionSpan.HasValue)
                ActionSpan = TimeSpan.FromMinutes(20);

            if (!ActionSpanScale.HasValue)
                ActionSpanScale = TimerScalePeriod.Hour;

            if (_mouseKeys == MouseExtenderButton.None)
                _mouseKeys = Constants.Defaults.MouseButton;

            if (!CheckUpdatesPeriod.HasValue)
                CheckUpdatesPeriod = MouseExtender.Logic.Enums.CheckUpdatesPeriod.Dayly;

            if (!InternetAccessConfigType.HasValue)
                InternetAccessConfigType = InternetAccessConfigurationType.AutoDetect;
        }

        private void SettingsChanged(object sender, EventArgs e)
        {
            UserSettings settings = sender as UserSettings;
            if (settings != null)
            {
                SettingsManager manager = new SettingsManager();
                manager.SaveSettings(settings);
            }
        }

        #endregion
    }
}
